home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / music / eked-m1.zoo / src / gm / gem_man.c < prev    next >
C/C++ Source or Header  |  1995-02-19  |  8KB  |  278 lines

  1. /*
  2.  *  EKED-M1 : Editor for Korg M1 synth; gem_man.c : GEM extensions
  3.  *  Copyright (C) 1995 Steven M. Eker (Steven.Eker@brunel.ac.uk)
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include <stddef.h>
  21. #include <osbind.h>
  22. #include <gemfast.h>
  23. #include <aesbind.h>
  24. #include <vdibind.h>
  25. #include "gem_man.h"
  26.  
  27. static int draw_button(PARMBLK *pb);
  28.  
  29. MFDB screen;
  30. GRECT desk;
  31. int char_w;
  32. int char_h;
  33. int nr_planes;
  34. USERBLK gm_button = {(void *) draw_button, 0};
  35. int gm_handle;
  36.  
  37. static MFDB button     = {0, 16, 16, 1, 0, 1, 0, 0, 0};
  38. static MFDB button_sel = {0, 16, 16, 1, 0, 1, 0, 0, 0};
  39. static MFDB check      = {0, 16, 16, 1, 0, 1, 0, 0, 0};
  40. static MFDB check_sel  = {0, 16, 16, 1, 0, 1, 0, 0, 0};
  41.  
  42. static int work_in[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2};
  43. static int work_out[57];
  44. static int phys_handle;
  45. static int roll_flag = R_ROLL;
  46.  
  47. void gm_init()
  48. {
  49.   static int but16[] = {
  50.     0x0000, 0x0000, 0x03c0, 0x0c30, 0x1008, 0x1008, 0x2004, 0x2004,
  51.     0x2004, 0x2004, 0x1008, 0x1008, 0x0c30, 0x03c0, 0x0000, 0x0000
  52.   };
  53.   static int but16_sel[] = {
  54.     0x0000, 0x0000, 0x03c0, 0x0c30, 0x1008, 0x13c8, 0x27e4, 0x27e4,
  55.     0x27e4, 0x27e4, 0x13c8, 0x1008, 0x0c30, 0x03c0, 0x0000, 0x0000
  56.   };
  57.   static int but8[] = {
  58.     0x07e0, 0x1818, 0x2004, 0x2004, 0x2004, 0x1818, 0x07e0, 0x0000
  59.   };
  60.   static int but8_sel[] = {
  61.     0x07e0, 0x1818, 0x23c4, 0x27e4, 0x23c4, 0x1818, 0x07e0, 0x0000
  62.   };
  63.   static int chk16[] = {
  64.     0x0000, 0x0000, 0x3ffc, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004,
  65.     0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x3ffc, 0x0000, 0x0000 
  66.   };
  67.   static int chk16_sel[] = {
  68.     0x0000, 0x0000, 0x3ffc, 0x300c, 0x2814, 0x2424, 0x2244, 0x2184,
  69.     0x2184, 0x2244, 0x2424, 0x2814, 0x300c, 0x3ffc, 0x0000, 0x0000 
  70.   };
  71.   static int chk8[] = {
  72.     0x3ffc, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x3ffc, 0x0000 
  73.   };
  74.   static int chk8_sel[] = {
  75.     0x3ffc, 0x381c, 0x2664, 0x2184, 0x2664, 0x381c, 0x3ffc, 0x0000 
  76.   };
  77.   int point[4];
  78.  
  79.   appl_init();
  80.   work_in[0] = Getrez() + 2;
  81.   phys_handle = graf_handle(&char_w, &char_h, &desk.g_w, &desk.g_h);
  82.   wind_get(DESK, WF_WORKXYWH, &desk.g_x, &desk.g_y, &desk.g_w, &desk.g_h);
  83.   gm_handle = gm_opnvwk();
  84.   GM_AES2VDI(point, &desk);
  85.   vs_clip(gm_handle, 1, point);
  86.   vsl_udsty(gm_handle, 0xAAAA);
  87.   vsl_type(gm_handle, 7);
  88.   vq_extnd(gm_handle, 1, work_out);
  89.   nr_planes = work_out[4];
  90.   if(char_h < 16){
  91.     button.fd_addr = (long) but8;
  92.     button_sel.fd_addr = (long) but8_sel;
  93.     button.fd_h = 8;
  94.     button_sel.fd_h = 8;
  95.     check.fd_addr = (long) chk8;
  96.     check_sel.fd_addr = (long) chk8_sel;
  97.     check.fd_h = 8;
  98.     check_sel.fd_h = 8;
  99.   }
  100.   else{
  101.     button.fd_addr = (long) but16;
  102.     button_sel.fd_addr = (long) but16_sel;
  103.     check.fd_addr = (long) chk16;
  104.     check_sel.fd_addr = (long) chk16_sel;
  105.   }
  106.   mg_init();
  107. }
  108.  
  109. void gm_exit()
  110. {
  111.   mg_exit();
  112.   gm_clsvwk(gm_handle);
  113.   appl_exit();
  114. }
  115.  
  116. int gm_opnvwk()
  117. {
  118.   int handle = phys_handle;
  119.  
  120.   v_opnvwk(work_in, &handle, work_out);
  121.   return handle;
  122. }
  123.  
  124. void gm_xorbox(GRECT *box)
  125. {
  126.   int point[4];
  127.  
  128.   vswr_mode(gm_handle, MD_XOR);
  129.   point[0] = box->g_x + 1;
  130.   point[2] = box->g_x + box->g_w - 2;
  131.   point[1] = point[3] = box->g_y;
  132.   v_pline(gm_handle, 2, point);
  133.   point[1] = point[3] = box->g_y + box->g_h - 1;
  134.   v_pline(gm_handle, 2, point);
  135.   point[1] = box->g_y + 1;
  136.   point[3] = box->g_y + box->g_h - 2;
  137.   point[0] = point[2] = box->g_x;
  138.   v_pline(gm_handle, 2, point);
  139.   point[0] = point[2] = box->g_x + box->g_w - 1;
  140.   v_pline(gm_handle, 2, point);
  141. }
  142.  
  143. static int draw_button(PARMBLK *pb)
  144. {
  145.   static int pens[] = {BLACK, WHITE};
  146.   static int points[8];
  147.   static GRECT rect;
  148.   MFDB *b;
  149.  
  150.   rect = *((GRECT *) &(pb->pb_x));
  151.   if(intersect((GRECT *) &(pb->pb_xc), &rect)){
  152.     GM_AES2VDI(points + 4, &rect);
  153.     points[0] = rect.g_x - pb->pb_x;
  154.     points[1] = rect.g_y - pb->pb_y;
  155.     points[2] = points[0] + points[6] - points[4];
  156.     points[3] = points[1] + points[7] - points[5];
  157.     if(((pb->pb_tree)[pb->pb_obj].ob_type >> 8) == 1)
  158.       b = (pb->pb_currstate & SELECTED) ? &button_sel : &button;
  159.     else
  160.       b = (pb->pb_currstate & SELECTED) ? &check_sel : ✓
  161.     vrt_cpyfm(gm_handle, 1, points, b, &screen, pens);
  162.   }
  163.   return 0;
  164. }
  165.  
  166. int gm_opaque(OBJECT *tree, int ob)
  167. {
  168.   int old, t;
  169.  
  170.   while(t = tree[ob].ob_type, (t == G_STRING || t == G_IMAGE || t == G_IBOX)){
  171.     do{
  172.       old = ob;
  173.       ob = tree[ob].ob_next;
  174.       if(ob == -1)
  175.         return old;
  176.     }while(tree[ob].ob_tail != old);
  177.   }
  178.   return ob;
  179. }
  180.  
  181. int gm_roll_mode(int mode)
  182. {
  183.   if(mode >= 0 && mode <= 2)
  184.     roll_flag = mode;
  185.   return roll_flag;
  186. }
  187.  
  188. int gm_roll(OBJECT *tree, int ob, int value, int min, int max,
  189.             UPDATE_FUNC_PTR update, REDRAW_FUNC_PTR redraw)
  190. {
  191.   int old_val, t, m_x, m_y, old_x, old_y, m_state, k_state, old_m_state, speed;
  192.   long delay;
  193.   GRECT rect;
  194.  
  195.   graf_mkstate(&old_x, &old_y, &old_m_state, &k_state);
  196.   if(old_m_state == 0 || (tree[ob].ob_state & DISABLED))
  197.     return value;
  198.  
  199.   wind_update(BEG_MCTRL);
  200.   objc_offset(tree, ob, &rect.g_x, &rect.g_y);
  201.   rect.g_w = tree[ob].ob_width;
  202.   rect.g_h = tree[ob].ob_height;
  203.   (void) intersect(&desk, &rect);
  204.   GM_BOUND_FIX(value, min, max);    /* make sure value in range */
  205.   (*update)(tree + ob, value);
  206.   tree[ob].ob_state |= SELECTED;
  207.   (*redraw)(tree, ob, &rect);
  208.  
  209.   if(roll_flag == R_ROLL){
  210.     speed = 200 / (max - min);        /* 200 pixels for full range */
  211.     GM_BOUND_FIX(speed, 4, 16);        /* but within sensible limits */
  212.     old_val = value;
  213.     for(;;){
  214.       graf_mkstate(&m_x, &m_y, &m_state, &k_state);
  215.       if(m_state == 0)
  216.         break;
  217.       if(m_state == old_m_state){
  218.         t = old_val + ((m_x - old_x) + (m_y - old_y)) / speed;
  219.         if(t > max)
  220.           t = max;
  221.         else if(t < min)
  222.           t = min;
  223.         if(value != t){
  224.           value = t;
  225.           (*update)(tree + ob, t);
  226.           (*redraw)(tree, ob, &rect);
  227.         }
  228.       }
  229.       else{
  230.         old_x = m_x;
  231.         old_y = m_y;
  232.         old_val = value;
  233.       }
  234.     }
  235.   }
  236.   else{
  237.     delay =  400;
  238.     for(;;){
  239.       evnt_timer(delay);
  240.       graf_mkstate(&m_x, &m_y, &m_state, &k_state);
  241.       if(m_state == 0)
  242.         break;
  243.       if(roll_flag == R_LEFTUP)
  244.         m_state ^= 3;
  245.       if(m_state == 1)
  246.         t = value - (value > min);
  247.       else if(m_state == 2)
  248.         t = value + (value < max);
  249.       else
  250.     continue;
  251.       if(value != t){
  252.         value = t;
  253.         (*update)(tree + ob, t);
  254.         (*redraw)(tree, ob, &rect);
  255.       }
  256.       if(delay > 40)
  257.         delay -= 20;
  258.     }
  259.   }
  260.   tree[ob].ob_state &= ~SELECTED;
  261.   (*redraw)(tree, ob, &rect);
  262.   wind_update(END_MCTRL);
  263.   return value;
  264. }
  265.  
  266. int intersect(GRECT *r1, GRECT *r2)
  267. {
  268.   int x, y;
  269.  
  270.   x = MAX(r1->g_x, r2->g_x);
  271.   y = MAX(r1->g_y, r2->g_y);
  272.   r2->g_w = MIN(r1->g_x + r1->g_w, r2->g_x + r2->g_w) - x;
  273.   r2->g_h = MIN(r1->g_y + r1->g_h, r2->g_y + r2->g_h) - y;
  274.   r2->g_x = x;
  275.   r2->g_y = y;
  276.   return (r2->g_w > 0) && (r2->g_h > 0);
  277. }
  278.